import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
import { Button, Input } from 'antd';
import React, { useMemo, useState } from 'react';
import { NodeProps, Position } from 'reactflow';
import { useContextSelector } from 'use-context-selector';

import CollapsibleSection from '@/components/CollapsibleSection';
import MyTooltip from '@/components/tooltip';
import { t } from '@/locales/i18n';
import { getNanoid } from '@/pages/chat/tools/tools';
import { NodeInputKeyEnum } from '@/types/workflow/constant';
import { FlowNodeInputItemType } from '@/types/workflow/io';
import { FlowNodeItemType } from '@/types/workflow/node';
import { UserSelectOptionItemType } from '@/types/workflow/template/system/interactive/type';
import { getHandleId } from '@/types/workflow/utils';

import { WorkflowContext } from '../../../context';
import { SourceHandle } from '../render/Handle';
import NodeCard from '../render/NodeCard';
import RenderInput from '../render/RenderInput';
import RenderOutput from '../render/RenderOutput';

const NodeUserSelect = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
  const { nodeId, inputs, outputs } = data;
  const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);

  const userSelectInputs = useMemo(() => {
    return inputs.filter((item) => !item.required && item.key === 'userSelectOptions');
  }, [inputs]);

  const [expandedSections, setExpandedSections] = useState<Set<'output' | 'input' | 'params'>>(
    new Set(['input']),
  );

  const toggleSection = (section: 'output' | 'input' | 'params') => {
    setExpandedSections((prev) => {
      const newSet = new Set(prev);
      if (newSet.has(section)) {
        newSet.delete(section);
      } else {
        newSet.add(section);
      }
      return newSet;
    });
  };

  const CustomComponent = useMemo(
    () => ({
      [NodeInputKeyEnum.userSelectOptions]: ({
        key: optionKey,
        value = [],
        ...props
      }: FlowNodeInputItemType) => {
        const options = value as UserSelectOptionItemType[];
        return (
          <div>
            {options.map((item, i) => (
              <div className="relative mb-4 flex items-center" key={item.key}>
                <div className="w-16 text-sm font-medium text-gray-600">
                  {t('option') + (i + 1)}
                </div>
                <Input
                  className="nodrag bg-white text-sm"
                  defaultValue={item.value}
                  onChange={(e) => {
                    const newVal = options.map((val) =>
                      val.key === item.key
                        ? {
                            ...val,
                            value: e.target.value,
                          }
                        : val,
                    );
                    onChangeNode({
                      nodeId,
                      type: 'updateInput',
                      key: optionKey,
                      value: {
                        ...props,
                        key: optionKey,
                        value: newVal,
                      },
                    });
                  }}
                />
                <div className="ml-auto flex items-center">
                  <MyTooltip title={t('common.Delete')}>
                    <Button
                      size="small"
                      type="text"
                      icon={<MinusCircleOutlined className="text-text-4 group-hover:text-error" />}
                      className="group mr-1 cursor-pointer text-text-4"
                      onClick={() => {
                        onChangeNode({
                          nodeId,
                          type: 'updateInput',
                          key: optionKey,
                          value: {
                            ...props,
                            key: optionKey,
                            value: options.filter((input) => input.key !== item.key),
                          },
                        });
                      }}
                    />
                  </MyTooltip>
                </div>
                <SourceHandle
                  nodeId={nodeId}
                  handleId={getHandleId(nodeId, 'source', item.key)}
                  position={Position.Right}
                  translate={[31, 0]}
                />
              </div>
            ))}

            <Button
              className="text-sm"
              icon={<PlusOutlined />}
              onClick={() => {
                onChangeNode({
                  nodeId,
                  type: 'updateInput',
                  key: optionKey,
                  value: {
                    ...props,
                    key: optionKey,
                    value: options.concat({ value: '', key: getNanoid() }),
                  },
                });
              }}
            >
              {t('core.module.Add_option')}
            </Button>
          </div>
        );
      },
    }),
    [nodeId, onChangeNode, t],
  );

  const RenderHandle = useMemo(
    () => ({
      [NodeInputKeyEnum.userSelectOptions]: ({
        key: optionKey,
        value = [],
        ...props
      }: FlowNodeInputItemType) => {
        const options = value as UserSelectOptionItemType[];
        return (
          <div>
            {options.map((item, i) => (
              <div className="relative w-full">
                <SourceHandle
                  nodeId={nodeId}
                  handleId={getHandleId(nodeId, 'source', item.key)}
                  position={Position.Right}
                  translate={[32, 0]}
                />
              </div>
            ))}
          </div>
        );
      },
    }),
    [nodeId, onChangeNode, t, expandedSections],
  );

  const Render = useMemo(() => {
    return (
      <NodeCard minW="420px" selected={selected} {...data}>
        <div className="flex flex-col gap-3 space-y-0">
          <CollapsibleSection
            title="选项配置"
            subtitle="配置用户选择选项"
            isExpanded={expandedSections.has('input')}
            onToggle={() => toggleSection('input')}
            tag={`${userSelectInputs.length > 0 ? userSelectInputs[0].value.length : ''}个选项`}
            type="input"
          >
            {expandedSections.has('input') && (
              <RenderInput
                nodeId={nodeId}
                flowInputList={inputs}
                CustomComponent={CustomComponent}
              />
            )}
          </CollapsibleSection>
          <CollapsibleSection
            title={t('workflow.node.output')}
            subtitle={t('workflow.node.output_desc')}
            isExpanded={expandedSections.has('output')}
            onToggle={() => toggleSection('output')}
            type="output"
            className="pb-3"
          >
            <div className="max-h-[200px] overflow-y-auto px-2">
              <RenderOutput nodeId={nodeId} flowOutputList={outputs} />
            </div>
          </CollapsibleSection>
        </div>

        {!expandedSections.has('input') && (
          <div className="absolute bottom-24 right-6">
            {RenderHandle.userSelectOptions({ ...userSelectInputs[0] })}
          </div>
        )}
      </NodeCard>
    );
  }, [
    selected,
    data,
    expandedSections,
    userSelectInputs,
    nodeId,
    inputs,
    CustomComponent,
    outputs,
    RenderHandle,
  ]);

  return Render;
};
export default React.memo(NodeUserSelect);
